#ifndef CRUMBS_H_
#define CRUMBS_H_

//int crumbs_kvm_init(struct kvm *kvm);

//int is_syscall(struct kvm_vcpu *vcpu);
//int is_sysret(struct kvm_vcpu *vcpu);

#define SYS_READ 0
#define SYS_WRITE 1
#define SYS_OPEN 2
#define SYS_CLOSE 3
#define SYS_SOCKET 41
#define SYS_CONNECT 42
#define SYS_ACCEPT 43
#define SYS_SENDTO 44
#define SYS_RECVFROM 45
#define SYS_SENDMSG 46
#define SYS_RECVMSG 47
#define SYS_BIND 49
#define SYS_LISTEN 50

///proc/kvm_trace
#define KVM_TRACE_PROC "kvm_trace"

/*
 * ioctls for /dev/kvm: start/stop trace from host
 */
struct trace_control {
	char vm_ts[256];
	char tag[256];
	char ret[256];
};

#define KVM_START_TRACE       _IOWR(KVMIO, 0xE0, struct trace_control)
#define KVM_STOP_TRACE       _IOWR(KVMIO, 0xE1, struct trace_control)

int start_trace_from_host(struct kvm * kvm, char * tag);
int stop_trace_from_host(struct kvm * kvm);

struct file* file_open(const char* path, int flags, int rights);
int file_read(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size);
int file_write(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size);
void file_close(struct file* file);

int start_vhost_trace();
int stop_vhost_trace();

enum cpu_mode {
	UNDEF,
	PROT,
	PAE,
	LONG
};

struct fdnode {
	long fd;
	int vcpu_id;
	int cpu;
	unsigned long ticket;
	struct timeval tv;
	unsigned long cr3;
	unsigned long esp; /* or u32 */
	//u64 cr2;
	unsigned long syscall_number;
	//unsigned long ip;
	//struct in_addr ip;
	char srcip[18];
	char destip[18];
	unsigned long srcport;
	unsigned long destport;
	struct list_head list;
};

/* KVM proc Data structure */
struct _mydrv_struct {
/* … */
struct list_head list; /* Link */
char info [256]; /* Info to pass via procfs/seq files */
/* … */
};

struct crumbs_data{
	int running;
	unsigned long ticket;
	char tag[256];

	unsigned long fdlist_size;
	struct fdnode *fdnode_new;
	struct fdnode fdlisthead;

	spinlock_t proc_lock;

	struct timeval tv; //records the time when VM is created
	char tv_str[256];

	int (*start_trace)(struct kvm *, char *);
	int (*stop_trace)(struct kvm *);

	char id[16];
	u64 sysenter_cs_val;
	u64 efer_val;
	u8 idt_int_offset;
	u8 idt_replaced_offset;
	//int pae;
	enum cpu_mode mode;
	int idt_entry_size;
	int syscall_reg;
	int no_int;

	u64 sendto_address;

	//struct sctrace_singlestep singlestep;
#ifdef SHADOW_IDT
	struct shadow_idt shadow_idt;
#endif
};

#endif /* CRUMBS_H_ */
